package com.zhx.common.chat.controller;


import com.zhx.common.chat.domain.dto.MsgReadInfoDTO;
import com.zhx.common.chat.domain.vo.request.*;
import com.zhx.common.chat.domain.vo.response.ChatMessageReadResp;
import com.zhx.common.chat.domain.vo.response.ChatMessageResp;
import com.zhx.common.chat.service.ChatService;
import com.zhx.common.common.annotation.FrequencyControl;
import com.zhx.common.common.annotation.RateLimit;
import com.zhx.common.common.annotation.RateLimits;
import com.zhx.common.common.domain.vo.resp.ApiResult;
import com.zhx.common.common.domain.vo.resp.CursorPageBaseResp;
import com.zhx.common.common.service.rateLimit.Target;
import com.zhx.common.common.util.RequestHolder;
import com.zhx.common.user.domain.enums.BlackTypeEnum;
import com.zhx.common.user.service.cache.UserCache;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

@RestController
@RequestMapping("/capi/chat")
@Api(tags = "聊天相关接口")
@Slf4j
public class ChatController {

    @Resource
    private ChatService chatService;

    @Resource
    private UserCache userCache;


    /**
     *
     * @param request request.body ->
     *                @see com.zhx.common.chat.domain.entity.msg
     * 会将这个body保存到 Message.extra
     * @return
     */
    @PostMapping("/msg")
    @ApiOperation("发送消息")
    @FrequencyControl(time = 5,count = 3,target = FrequencyControl.Target.UID)
    @FrequencyControl(time = 30,count = 5,target = FrequencyControl.Target.UID)
    @FrequencyControl(time = 60,count = 10,target = FrequencyControl.Target.UID)
    public ApiResult<ChatMessageResp> sendMsg(@Valid @RequestBody ChatMessageReq request){
        Long msgId = chatService.sendMsg(request, RequestHolder.get().getUid());
        //返回完整消息格式给自己，方便前端展示,
        return ApiResult.success(chatService.getMsgResp(msgId,RequestHolder.get().getUid()));
    }


    /**
     * 获取消息分页列表
     *
     * @param req 分页和筛选条件请求对象
     * @return ApiResult<CursorPageBaseResp<ChatMessageResp>> 包含消息分页列表的响应对象，其中消息列表会过滤掉用户黑名单中的发送者。
     */
    @GetMapping("/public/msg/page")
    @ApiOperation("消息列表")
    @FrequencyControl(time = 120,count = 20,target = FrequencyControl.Target.IP)
    public ApiResult<CursorPageBaseResp<ChatMessageResp>> getMsgPage(@Valid ChatMessagePageReq req){
        // 从聊天服务获取消息分页，基于提供的请求条件和当前用户的UID
        CursorPageBaseResp<ChatMessageResp> msgPage = chatService.getMsgPage(req,RequestHolder.get().getUid());
        // 获取用户黑名单，并从消息列表中移除黑名单用户的消息
        Set<String> blackMembers = userCache.getBlackMap().getOrDefault(BlackTypeEnum.UID.getType(), new HashSet<>());
        msgPage.getList().removeIf(a -> blackMembers.contains(a.getFromUser().getUid().toString()));
        // 返回成功响应，包含过滤后的消息分页列表
        return ApiResult.success(msgPage);
    }


    @PutMapping("/msg/recall")
    @ApiOperation("撤回消息")
    @FrequencyControl(time = 20, count = 3, target = FrequencyControl.Target.UID)
    public ApiResult<Void> recallMsg(@Valid @RequestBody ChatMessageBaseReq req){
        chatService.recallMsg(RequestHolder.get().getUid(),req);
        return ApiResult.success();
    }

    @PutMapping("/msg/mark")
    @ApiOperation("消息标记")
    @FrequencyControl(time = 10, count = 5, target = FrequencyControl.Target.UID)
    public ApiResult<Void> setMsgMark(@Valid @RequestBody ChatMessageMarkReq request) {
        chatService.setMsgMark(RequestHolder.get().getUid(), request);
        return ApiResult.success();
    }

    @GetMapping("/msg/read/page")
    @ApiOperation("消息的已读未读列表")
    public ApiResult<CursorPageBaseResp<ChatMessageReadResp>> getReadPage(@Valid ChatMessageReadReq request) {
        Long uid = RequestHolder.get().getUid();
        return ApiResult.success(chatService.getReadPage(uid, request));
    }

    @GetMapping("/msg/read")
    @ApiOperation("获取消息的已读未读总数(批量)")
    public ApiResult<Collection<MsgReadInfoDTO>> getReadInfo(@Valid ChatMessageReadInfoReq request) {
        Long uid = RequestHolder.get().getUid();
        return ApiResult.success(chatService.getMsgReadInfo(uid, request));
    }

    @PutMapping("/msg/read")
    @ApiOperation("消息阅读上报")
    public ApiResult<Void> msgRead(@Valid @RequestBody ChatMessageMemberReq request) {
        Long uid = RequestHolder.get().getUid();
        chatService.msgRead(uid, request);
        return ApiResult.success();
    }

    @RateLimit(time = 5,count = 3,target = Target.IP)
    @RateLimit(time = 30,count = 5,target = Target.IP)
    @RateLimit(time = 60,count = 10,target = Target.IP)
    @PostMapping("/testRateLimit")
    public void test(){
        System.out.println("good");
    }
}
